﻿using System.Collections.Generic;
using System.Linq;
using Medianamik.Core.Configuration;
using System.Configuration;

namespace Medianamik.Core.Action
{
    public class NodeTypeGenTableActionHandler : IActionHandler
    {
        private static readonly MedianamikConfigSection Config = 
            (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);

        public void Initialize(ActionManager events)
        {
            events.AfterCreateNodeType += AfterSaveNodeType;
            events.AfterUpdateNodeType += AfterSaveNodeType;
            events.AfterDeleteNodeType += AfterDeleteNodeType;

            //events.AfterCreateNodeTypeProperty += AfterCreateNodeTypeProperty;
            //events.AfterDeleteNodeTypeProperty += AfterDeleteNodeTypeProperty;
            events.AfterCreateNodeTypeProperties += AfterCreateNodeTypeProperties;
            events.AfterDeleteNodeTypeProperties += AfterDeleteNodeTypeProperties;
            events.AfterImplementNodeTypeInterfaces += AfterImplementNodeTypeInterfaces;
            events.AfterUnimplementNodeTypeInterfaces += AfterUnimplementNodeTypeInterfaces;
        }

        public string Description
        {
            get { return "Met à jour les tables générées lors de la création / modification d'un type"; }
        }

        void AfterDeleteNodeType(ActionEventArgs<NodeType> args)
        {
            var codeService = new CodeGeneration.CodeService();
            //Supprimer la table générée
            codeService.DeleteTableAndView(args.Item);
            codeService.UpdateViewForParents(args.Item); 
        }

        void AfterSaveNodeType(ActionEventArgs<NodeType> args)
        {
            //Mettre à jour les tables générées
            var codeService = new CodeGeneration.CodeService();

            if (Config.EnableTableGenerator && args.Item.IsGenerated
                && !codeService.CheckTableExists(args.Item))
            {
                codeService.GenerateTableAndView(args.Item);
                codeService.UpdateViewForParents(args.Item); 
                codeService.FillTable(args.Item);
            }
        }

        void AfterCreateNodeTypeProperties(ActionEventArgs<IEnumerable<NodeTypeProperty>> args)
        {
            if (args == null || args.Item == null || args.Item.Count() < 1)
                return;

            //Mettre à jour les tables générées
            if (Config.EnableTableGenerator)
            {
                var codeService = new CodeGeneration.CodeService();
                var type = args.Item.First().NodeType;

                if (!codeService.CheckTableExists(type))
                {
                    if (type.IsGenerated)
                    {
                        codeService.GenerateTableAndView(type);
                        codeService.UpdateViewForParents(type);
                        codeService.FillTable(type);
                    }
                }
                else
                {
                    codeService.AddColumns(args.Item);
                }
            }
        }

        void AfterDeleteNodeTypeProperties(ActionEventArgs<IEnumerable<NodeTypeProperty>> args)
        {
            if (args == null || args.Item == null || args.Item.Count() < 1)
                return;

            //Mettre à jour les tables générées
            if (Config.EnableTableGenerator )
            {
                var codeService = new CodeGeneration.CodeService();
                var type = args.Item.First().NodeType;

                if (!codeService.CheckTableExists(type))
                {
                    if (type.IsGenerated)
                    {
                        codeService.GenerateTableAndView(type);
                        codeService.UpdateViewForParents(type);
                        codeService.FillTable(type);
                    }
                }
                else
                {
                    codeService.RemoveColumns(args.Item);
                }
            }
        }

        void AfterImplementNodeTypeInterfaces(ActionEventArgs<IEnumerable<NodeTypeInterfaceImplementation>> args)
        {
            if (args == null || args.Item == null || args.Item.Count() < 1)
                return;

            var type = args.Item.First().Owner;

            //Mettre à jour les vues des interfaces
            if (Config.EnableTableGenerator & type.IsGenerated)
            {
                var codeService = new CodeGeneration.CodeService();
                codeService.GenerateView(args.Item.First().NodeTypeInterface);
            }
        }

        void AfterUnimplementNodeTypeInterfaces(ActionEventArgs<IEnumerable<NodeTypeInterfaceImplementation>> args)
        {
            if (args == null || args.Item == null || args.Item.Count() < 1)
                return;

            var type = args.Item.First().Owner;

            //Mettre à jour les vues des interfaces
            if (Config.EnableTableGenerator & type.IsGenerated)
            {
                var codeService = new CodeGeneration.CodeService();
                codeService.GenerateView(args.Item.First().NodeTypeInterface);
            }
        }
    }
}
